module lang.d.sts.declarations.dparameterlist;

import lang.d.sts.declarations.ddeclaration;
import lang.d.types.dtype;
import lang.d.visitors.dvisitor;
import lang.d.sts.expressions.dexpression;

enum InOut: ubyte {
    IN,
    REF,
    OUT,
    LAZY
}

class DParameter: DDeclaration {
    private string myName;
    private DType myType;
    private InOut myStorageClass;
    private DExpression myDefaultInitializer;

    public this() {
        super(NONE);
    }

    public void setName(in string name) {
        myName = name;
    }

    public string getName() const {
        return myName;
    }

    public void setType(DType type) {
        myType = type;
    }

    public DType getType() {
        return myType;
    }

    public void setStorageClass(InOut storageClass) {
        myStorageClass = storageClass;
    }

    public void setDefaultInitializer(DExpression defaultInitilizer) {
        myDefaultInitializer = defaultInitilizer;
    }

    public DExpression getDefaultInitializer() {
        return myDefaultInitializer;
    }

    public bool hasInitializer() {
        return (myDefaultInitializer !is null);
    }

    override public void accept(DVisitor visitor) {
        visitor.visitParameter(this);
    }
}

enum VarArgsType: ubyte {
    NONE,
    OLD_STYLE,
    TYPE_SAFE
}

class DParameterList: DDeclaration {
    private DParameter[] myParameters;
    private VarArgsType myVarArgsType = VarArgsType.NONE;

    public this() {
        super(NONE);
    }

    public DParameter opIndex(uint i) {
        return myParameters[i];
    }

    public uint length() @property {
        return myParameters.length;
    }

    public void opCatAssign(DParameter parameter) {
        myParameters ~= parameter;
    }

    public void setVarArgsType(VarArgsType type) {
        myVarArgsType = type;
    }

    public VarArgsType getVarArgsType() const {
        return myVarArgsType;
    }

    override public void accept(DVisitor visitor) {
        visitor.visitParameterList(this);
    }
}
